<template>
  <div :style="cssVars" class="ganttwrap">
    <div class="header">
      <div class="btns">
        <div
          :class="gantt_show_type == 'day' ? 'active' : ''"
          @click="changetype('day')"
        >
          日
        </div>
        <div
          :class="gantt_show_type == 'week' ? 'active' : ''"
          @click="changetype('week')"
        >
          周
        </div>
        <div
          :class="gantt_show_type == 'month' ? 'active' : ''"
          @click="changetype('month')"
        >
          月
        </div>
      </div>
      <div class="btns btns2">
        <div :class="showdate ? 'active' : ''" @click="showdate = !showdate">
          跟随
        </div>
      </div>
      <div class="btns3">
        <div
          v-show="changeStatus == 'start'"
          :style="{ color: style.btns.color, fontSize: '22px' }"
          @click="changeScale('start')"
        >
          <svg-icon icon-class="icon_start" class="icon-card"></svg-icon>
        </div>
        <div
          v-show="changeStatus == 'zanting'"
          :style="{ color: style.btns.color, fontSize: '22px' }"
          @click="changeScale('zanting')"
        >
          <svg-icon icon-class="icon_pause" class="icon_pause"></svg-icon>
        </div>

        <div
          :style="{ color: style.btns.color, fontSize: '22px' }"
          @click="changeScale('jieshu')"
        >
          <svg-icon icon-class="icon_end" class="icon_end"></svg-icon>
        </div>
      </div>
      <div @click="putgantt" class="btns4">
        <div :style="{ color: style.btns.color, fontSize: '22px' }">
          <svg-icon
            icon-class="icon_pull_down"
            class="icon_pull_down"
          ></svg-icon>
        </div>
      </div>

      <!-- <button @click="step = 1">1倍</button>
      <button @click="step = 2">2倍</button>
      <button @click="step = 5">5倍</button>
      <button @click="step = 10">10倍</button> -->
    </div>
    <div ref="gantt" class="ganttRef" :id="id"></div>
    <div ref="blur" class="blur"></div>
  </div>
</template>

<script>
import { gantt } from "dhtmlx-gantt"; // 核心模块
import "dhtmlx-gantt/codebase/dhtmlxgantt.css"; // 样式模块
import Dayjs from "dayjs";
import store from "@/js/store/state.js";
// import svg from "../../image/icons/svg/icon_start.svg";
import status from "@/js/main/status.js";

export default {
  props: {
    element: {
      type: Object,
    },
    id: {
      type: String,
    },
  },
  data() {
    return {
      // 深色浅色样式
      style: {
        btns: {
          color: "#000",
          active_color: "#fff",
        },
        blur: "rgba(255, 255, 255, 0.91)",
      },
      changeStatus: "start",
      putgantt_flag: false,
      // 数据信息--必须要有start_time字段以及duration字段
      tasks: {
        data: null,
      },
      dateToStr: null,
      gantt_show_type: "month",
      currentElementList: store.getCurrentElementList(),
      tileLayerId: "",
      marker: null, //甘特图marker对象
      EndTime: null, //结束时间
      timer: null, //定时器
      start: false, //是否开始模拟
      zanting: false, //是否暂停模拟
      stop: false, //是否结束模拟
      step: 1, //倍数
      nowtime: 0, //当前进度
      date: null, // 日期
      month: null, // 月份
      year: null, // 年份
      showdate: false, //模拟时跟随进度
    };
  },
  computed: {
    cssVars() {
      return {
        "--BtnsColor": this.style.btns.color,
        "--BtnsActiveColor": this.style.btns.active_color,
        "--blur": this.style.blur,
      };
    },
    shortcut() {
      return status.shortcut;
    },
  },
  watch: {
    "element.data.reset": {
      handler(newName, oldName) {
        if (this.element.data.reset) {
          this.init();
        }
      },
      deep: true,
    },
    "element.data.treedata": {
      handler(newName, oldName) {
        if (this.element.data.treedata) {
          this.init();
        }
      },
      deep: true,
    },
    shortcut: {
      handler(newName, oldName) {
        if (newName) {
          this.init();
        }
      },
      deep: true,
    },
  },
  methods: {
    putgantt() {
      this.putgantt_flag = !this.putgantt_flag;
      if (this.putgantt_flag) {
        this.$refs.gantt.style.height = "0";
        this.$refs.blur.style.height = "40px";
      } else {
        this.$refs.gantt.style.height = "calc(100% - 40px)";
        this.$refs.blur.style.height = "100%";
      }
    },
    /**
     * @function 月展示
     * @param date
     */
    weekScaleTemplate(date) {
      console.log("[ date ] >", date);
      const mouthMap = {
        Jan: "一月",
        Feb: "二月",
        Mar: "三月",
        Apr: "四月",
        May: "五月",
        Jun: "六月",
        Jul: "七月",
        Aug: "八月",
        Sept: "九月",
        Oct: "十月",
        Nov: "十一月",
        Dec: "十二月",
      };
      // 可以时使用dayjs 处理返回
      const dateToStr = gantt.date.date_to_str("%d");
      const mToStr = gantt.date.date_to_str("%M");
      const endDate = gantt.date.add(
        gantt.date.add(date, 1, "week"),
        -1,
        "day"
      );
      console.log("[ mToStr(date) ] >", mToStr(date));
      // 处理一下月份
      return `${dateToStr(date)} 号 - ${dateToStr(endDate)} 号 (${mToStr(
        date
      )})`;
    },
    /**
     * 周展示
     * @param date
     */
    dayFormat(date) {
      const weeks = [
        "星期日",
        "星期一",
        "星期二",
        "星期三",
        "星期四",
        "星期五",
        "星期六",
      ];
      return weeks[Dayjs(date).day()];
    },
    init() {
      // 初始化数据
      this.convertToTree(this.element.data.treedata);
      // 绑定图层id
      this.tileLayerId = this.element.data.tilelayerid;
      // this.currentElementList[0].data.reset = "";
      // console.log(this.tasks.data, "this.tasks.data");
      gantt.clearAll();

      gantt.i18n.setLocale("cn");
      // gantt.init("gantt_here");
      gantt.plugins({
        marker: true,
        tooltip: true,
      });
      // 配置右侧图表的日期信息 默认月份
      gantt.config.scales = [{ unit: "month", step: 1, format: "%M, %Y" }];
      // 用户可以通过拖拽调整行高
      gantt.config.resize_rows = false;
      // 图表项目栏可以任意拖拽（任意节点下)
      gantt.config.order_branch = false;
      gantt.config.order_branch_free = false;
      // 点击表头可排序
      gantt.config.sort = false;
      // // 4.1 甘特图的行高
      // gantt.config.row_height = 30;
      // // 4.2 甘特图的表头高度
      // gantt.config.scale_height = 40;
      // // 4.3 设置滚动条宽/高度
      gantt.config.scroll_size = 5;
      // 配置左侧列表表头
      gantt.config.columns = [
        {
          name: "编码名称",
          width: 200,
          tree: true,
          label: "编码名称",
          align: "left",
          resize: true,
          template: (obj) => {
            // #icon-feeds-fill
            // #icon-folder-fill
            return `
            <svg style="width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
    color:${this.element.data.style == "light" ? "#555555" : "#B3B3B3"};
    " class="svg-icon" aria-hidden="true">
      <use xlink:href="${
        typeof obj["构件Id"] == "string" ? "#icon-feeds-fill" : "#icon-folder"
      }" />
    </svg> ${obj["编码名称"]}
            `;
          },
        },
        {
          name: "start_date",
          width: 100,
          label: "实际开始时间",
          align: "center",
          resize: true,
          template: function (obj) {
            return obj["start_date"];
          },
        },
        {
          name: "实际完成时间",
          width: 100,
          label: "实际完成时间",
          align: "center",
          resize: true,
          template: function (obj) {
            return obj["实际完成时间"];
          },
        },
        {
          name: "计划开始时间",
          width: 100,
          label: "计划开始时间",
          align: "center",
          resize: true,
          template: function (obj) {
            return obj["计划开始时间"];
          },
        },
        {
          name: "计划完成时间",
          width: 100,
          label: "计划完成时间",
          align: "center",
          resize: true,
          template: function (obj) {
            return obj["计划完成时间"];
          },
        },
      ];
      // gantt.attachEvent("onTaskDblClick", function (id, e) {
      //   console.log("[ id ] >", id);
      //   console.log("[ e ] >", e);
      //   return false;
      // });
      // tooltip弹框配置项
      gantt.templates.tooltip_text = function (start, end, task) {
        return (
          "<b>标题:</b> " +
          task["编码名称"] +
          "<br/><span>开始:</span> " +
          gantt.templates.tooltip_date_format(start) +
          "<br/><span>结束:</span> " +
          gantt.templates.tooltip_date_format(end)
        );
      };
      if (document.getElementById(this.id)) {
        gantt.init(document.getElementById(this.id)); // 初始化 DOM
        gantt.parse(this.tasks); // 传入 tasks
        gantt.render();
        // 动态样式
        gantt.$container.className = this.element.data.style;
      }
    },

    // 进度模拟
    changeScale(type) {
      console.log("[ type ] >", type);
      if (!this.element.data.tilelayerid) {
        this.$message.error("未选择图层id");
        return;
      }
      console.log("[ 111 ] >", this.tasks.data);
      if (!this.tasks.data.length) {
        this.$message.error("未导入数据");
        return;
      }
      if (type == "start") {
        this.changeStatus = "zanting";
        if (!this.zanting) {
          __g
            ? __g.tileLayer.hideAllActors(this.element.data.tilelayerid, null)
            : this.$message.error("未初始化");
          // marker标记要出来要确保gantt已经初始化 -------- 注意这点，放在init之前是出不来的
          this.dateToStr = gantt.date.date_to_str(gantt.config.task_date);
          const timesplit = this.tasks.data[0].实际开始时间.split("/");
          const timeendsplit = this.tasks.data[0].实际完成时间.split("/");
          this.EndTime = Dayjs(
            new Date(timeendsplit[0], timeendsplit[1] - 1, timeendsplit[2], 12)
          ).format("YYYY/MM/DD");
          this.date = timesplit[2]; // 日期
          this.month = timesplit[1] - 1; // 月份
          this.year = timesplit[0]; // 年份
          this.zanting = false;
        }
        this.dateToStr = gantt.date.date_to_str(gantt.config.task_date);
        const today = new Date(this.year, this.month, this.date, 12);
        this.marker && gantt.deleteMarker(this.marker);
        this.marker = gantt.addMarker({
          start_date: today,
          css: "today",
          text: "",
          // text: this.tasks.data[0].实际开始时间,
          title: "Today: " + this.dateToStr(today),
        });
        this.showActor(Dayjs(today).format("YYYY/MM/DD"));
        // const dateToStr = gantt.date.date_to_str(gantt.config.task_date);
        clearInterval(this.timer);
        // let date = timesplit[2]; // 日期
        // let month = timesplit[1] - 1; // 月份
        // let year = timesplit[0]; // 年份
        // let rate = 1; // 默认一倍速

        // let thityOne = [1, 3, 5, 7, 8, 10, 12]; // 31天的月份
        this.timer = setInterval(() => {
          // 按天进行模拟
          if (this.gantt_show_type == "day") {
            this.date = Number(this.date) + 1;
            let today = gantt.getMarker(this.marker);
            today.start_date = new Date(this.year, this.month, this.date, 12);
            today.title = this.dateToStr(today.start_date);
            today.text = "";
            // today.text = Dayjs(today.start_date).format("YYYY/MM");
            gantt.updateMarker(this.marker);
            this.showActor(Dayjs(today.start_date).format("YYYY/MM/DD"), "day");
            this.showdate && gantt.showDate(today.start_date); //定位到当前时间
          }
          // 按周进行模拟
          if (this.gantt_show_type == "week") {
            this.date = Number(this.date) + 7;
            let today = gantt.getMarker(this.marker);
            today.start_date = new Date(this.year, this.month, this.date, 12);
            today.title = this.dateToStr(today.start_date);
            today.text = "";
            // today.text = Dayjs(today.start_date).format("YYYY/MM");

            gantt.updateMarker(this.marker);
            this.showActor(
              Dayjs(today.start_date).format("YYYY/MM/DD"),
              "week"
            );
            this.showdate && gantt.showDate(today.start_date); //定位到当前时间
          }
          // 按月进行模拟
          if (this.gantt_show_type == "month") {
            this.month = Number(this.month) + 1;
            let today = gantt.getMarker(this.marker);
            today.start_date = new Date(this.year, this.month, this.date, 12);
            today.title = this.dateToStr(today.start_date);
            today.text = "";
            // today.text = Dayjs(today.start_date).format("YYYY/MM");
            gantt.updateMarker(this.marker);
            this.showActor(Dayjs(today.start_date).format("YYYY/MM"), "month");
            this.showdate && gantt.showDate(today.start_date); //定位到当前时间
          }
        }, 1000 / this.step);
      }
      // 暂停
      if (type == "zanting") {
        this.changeStatus = "start";
        this.zanting = true;
        clearInterval(this.timer);
      }
      // 结束
      if (type == "jieshu") {
        this.changeStatus = "start";
        clearInterval(this.timer);
        this.date = null;
        this.month = null;
        this.year = null;
        this.zanting = false;
        this.init();
        __g.tileLayer.showAllActors(this.element.data.tilelayerid, null);
      }
    },
    // 进度模拟-显示构件
    showActor(time, type) {
      const ShowObj = [];
      this.tasks.data.forEach((item) => {
        if (item["构件Id"] && Dayjs(item["实际完成时间"]).isSame(time, type)) {
          ShowObj.push(item["构件Id"]);
        }
      });
      console.log("[ ShowObj ] >", ShowObj);
      if (ShowObj.length) {
        __g.tileLayer.showActors(
          [
            {
              id: this.element.data.tilelayerid,
              objectIds: ShowObj,
            },
          ],
          null
        );
        __g.tileLayer.highlightActors(
          [
            {
              id: this.element.data.tilelayerid,
              objectIds: ShowObj,
            },
          ],
          null
        );
        setTimeout(() => {
          //停止所有Actor高亮
          __g.tileLayer.stopHighlightAllActors();
        }, 2000);
      }
      // 延时两秒结束
      setTimeout(() => {
        if (Dayjs(time).isSame(this.EndTime, type)) {
          this.changeScale("jieshu");
          this.$message("模拟结束");
        }
      }, 2000);
    },
    // 切换甘特图显示类型（月 周 日）
    changetype(type) {
      this.gantt_show_type = type;
      // this.changeScale("jieshu"); //停止模拟
      // this.init(); //重新初始化

      let scales = [];
      if (type == "day") {
        scales.push({ unit: "month", step: 1, format: "%M, %Y" });
        // scales.push({ unit: "week", step: 1, format: this.weekScaleTemplate });
        scales.push({ unit: "day", step: 1, format: this.dayFormat });
      }
      if (type == "week") {
        scales.push({ unit: "month", step: 1, format: "%M, %Y" });
        scales.push({ unit: "week", step: 1, format: this.weekScaleTemplate });
        // scales.push({ unit: "day", step: 1, format: this.dayFormat });
      }
      if (type == "month") {
        scales.push({ unit: "month", step: 1, format: "%M, %Y" });
        // scales.push({ unit: "week", step: 1, format: this.weekScaleTemplate });
        // scales.push({ unit: "day", step: 1, format: this.dayFormat });
      }

      gantt.config.scales = scales;

      gantt.render(); //重新render更改显示类型
    },
    // 转换树结构
    arrayToTree(data, type) {
      let result = [];
      let itemMap = {};
      for (let i = 0; i < data.length; i++) {
        let item = data[i];
        let id = type == "pid" ? item.id : item["编码"];
        let pid = type == "pid" ? item.pid : item["父节点编码"];
        if (!itemMap[id]) {
          itemMap[id] = {
            children: [],
          };
        }
        itemMap[id] = {
          ...item,
          children: itemMap[id]["children"],
        };
        let treeItem = itemMap[id];
        if (pid === null) {
          result.push(treeItem);
        } else {
          if (!itemMap[pid]) {
            itemMap[pid] = {
              children: [],
            };
          }
          itemMap[pid]["children"].push(treeItem);
        }
      }
      return result;
    },
    // 把扁平化的数据转成甘特图所需要的数据格式
    convertToTree(data) {
      let tempdata = data;
      for (let i = 0; i < tempdata.length; i++) {
        const item = tempdata[i];
        let path = item["编码"].split("-");
        if (path.length > 1) {
          item["id"] = path.join();
          item["pid"] = path.slice(0, path.length - 1).join();
        } else {
          item["id"] = path.join();
          item["pid"] = null;
        }
      }

      this.GetGanttData(tempdata);
      // return this.arrayToTree(tempdata, "pid");
    },
    // 转甘特图数据
    GetGanttData(data) {
      const result = [];
      for (let i = 0; i < data.length; i++) {
        const element = data[i];
        if (typeof element["计划开始时间"] == "string") {
          result.push({
            id: element.id, //id
            parent: element.pid, //父id
            start_date: Dayjs(element["计划开始时间"]).format("DD-MM-YYYY"), //开始时间
            open: true,
            text: element["编码名称"],
            duration: Dayjs(element["计划完成时间"]).diff(
              Dayjs(element["计划开始时间"]),
              "days"
            ),
            ...element,
          });
        }
      }
      console.log(result, "result");
      this.tasks.data = result;
    },

    // 样式
    changestyle() {
      if (this.element.data.style == "light") {
        console.log("[ this.element ] >", this.element.data);
        this.style.btns.active_color = "#fff";
        this.style.btns.color = "#000";
        this.style.blur = "rgba(255, 255, 255, 0.8)";
      } else {
        this.style.btns.active_color = "#000";
        this.style.btns.color = "#fff";
        this.style.blur = "rgba(0, 0, 0, 0.8)";
      }
    },
  },
  created() {},
  mounted() {
    this.changestyle();
    this.init();
  },
  beforeCreate() {},
  beforeMount() {},
  beforeUpdate() {},
  updated() {},
  beforeDestroy() {
    clearInterval(this.timer);
  },
  destroyed() {},
  activated() {},
  components: {},
};
</script>

<style lang="scss" scoped>
.ganttwrap {
  overflow-y: hidden;
  // position: relative;
  display: flex;
  flex-direction: column;
  justify-content: end;

  // background: #fff;
  .header {
    height: 40px;
    display: flex;
    position: relative;
    border-radius: 4px 4px 4px 4px;
    border: 1px solid #ffffff;
    align-items: center;
    .btns {
      // margin-top: 5px;
      // width: 116px;
      height: 24px;
      border-radius: 2px 2px 2px 2px;
      border: 1px solid #888888;
      display: flex;
      padding: 3px 5px;
      margin-left: 10px;
      box-sizing: border-box;
      // justify-content: space-around;
      // align-items: center;
      > div {
        font-size: 12px;
        width: 36px;
        height: 18px;
        font-weight: 500;
        border-radius: 2px 2px 2px 2px;
        cursor: pointer;
        display: flex;
        justify-content: center;
        align-items: center;

        color: var(--BtnsColor);
        &.active {
          // color: aqua;
          color: var(--BtnsActiveColor);

          background: #317ffb;
        }
      }
    }
    .btns2 {
      margin-left: 20px;
      > div {
        width: 40px;
      }
    }
    .btns3 {
      margin-left: 420px;
      display: flex;
      justify-content: space-around;
      align-items: center;
      > div {
        margin: 0 5px;
        cursor: pointer;
      }
    }
    .btns4 {
      position: absolute;
      top: 5px;
      right: 20px;
      cursor: pointer;
    }
  }
  .ganttRef {
    height: calc(100% - 40px);
    // overflow-y: scroll;
    overflow: hidden;
    transition: all 0.5s;
  }
  .blur {
    width: 100%;
    height: 100%;
    position: absolute;
    bottom: 0;
    transition: all 0.5s;
    z-index: -1;
    // filter: blur(10px);
    background: var(--blur);
  }
}
</style>
<style lang="scss">
.gantt_task_content {
  /* text-align: left !important;
  text-indent: 2em; */
  display: flex;
  justify-content: left;
  margin-left: 10px;
}
/* 任务线 */
.gantt_task_line {
  height: 24px !important;
  line-height: 24px !important;
  margin-top: 4px;
  border: none !important;
  border-radius: 2px 2px 2px 2px !important;
  &:nth-child(5n + 1) {
    background: #295aac;
  }
  &:nth-child(5n + 2) {
    background: #448230;
  }
  &:nth-child(5n + 3) {
    background: #1b7595;
  }
  &:nth-child(5n + 4) {
    background: #a06731;
  }
  &:nth-child(5n + 5) {
    background: #1b858e;
  }
}
.gantt_row.odd,
.gantt_task_row.odd,
.gantt_row,
.gantt_task_row {
  background: #00000000;
}
.gantt_grid_scale,
.gantt_task_scale,
.gantt_task_vscroll {
  background: #00000000;
}

.light {
  .gantt_container {
    background: #fff;
  }
  .gantt_task_cell,
  .gantt_cell {
    color: #222222 !important;
    border-right: none !important;
  }
  .gantt_grid_scale .gantt_grid_head_cell {
    font-size: 12px;
    font-family: Source Han Sans CN, Source Han Sans CN;
    font-weight: 600;
    color: #1d2129;
  }
}
.dark {
  .gantt_container {
    background: #000;
  }
  .gantt_task_cell,
  .gantt_cell {
    color: #fff !important;
    border-right: none !important;
  }
  .gantt_grid_scale .gantt_grid_head_cell {
    font-size: 12px;
    font-family: Source Han Sans CN, Source Han Sans CN;
    font-weight: 600;
    color: #fff;
  }
}
// .gantt_tooltip {
//   // background: var(--gantt_tooltipbg) !important;
//   background: #000 !important;
//   // background: var(--gantt_tooltipbg) !important;
//   color: var(--gantt_tooltipcolor) !important;
// }
/* 里程碑 */
.gantt_task_line.gantt_milestone {
  width: 30px !important;
  height: 30px !important;
  border: none !important;
  background-color: inherit !important;
  background-size: cover;
}
/* 里程碑icon */
.gantt_task_line.gantt_milestone .gantt_task_content {
  margin-top: -8px;
  transform: rotate(0deg) !important;
  /* background-image: url("iconURL") !important; */
}
/* 左侧悬浮单元格背景色 */
.gantt_grid_data .gantt_row.odd:hover,
.gantt_grid_data .gantt_row:hover {
  background-color: rgba(71, 71, 71, 0.644) !important;
}
/* 选中一列背景色 */
.gantt_grid_data .gantt_row.gantt_selected,
.gantt_grid_data .gantt_row.odd.gantt_selected,
.gantt_task_row.gantt_selected {
  background-color: rgba(71, 71, 71, 0.644) !important;
}
/* 选中一列每个单元格右border颜色 */
.gantt_task_row.gantt_selected .gantt_task_cell {
  border-right-color: rgba(71, 71, 71, 0.644) !important;
}

/* 任务名前的logo */
.gantt_tree_icon.gantt_file,
.gantt_tree_icon.gantt_folder_open,
.gantt_tree_icon.gantt_folder_closed {
  width: 10px;
  background-image: none;
}
.gantt_tree_content {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 标记线 */
.gantt_marker {
  // background-color: brown;
  background: rgba(255, 54, 50, 0.3);
  position: relative;
  top: 22px;
}
.gantt_marker::after {
  content: "";
  // width: 14px;
  // height: 22px;
  position: absolute;
  left: -9px;
  top: -22px;
  // background: rgba(255, 54, 50, 0.3);
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 24px 10px 0 10px;
  border-color: rgba(255, 54, 50, 0.3) transparent transparent transparent;
}

/*滚动条里面轨道*/
// .gantt-wrapper ::-webkit-scrollbar-track {
//   background-color: rgba(0, 0, 0, 0.2);
// }
/*滚动条里面拖动条*/
// .gantt_ver_scroll {
//   width: 5px !important;
// }
// .gantt_layout_cell .gantt_hor_scroll {
//   height: 2px !important;
// }
</style>
